package com.ape.mapsa.bpm.service;

import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.ActivitiTaskAlreadyClaimedException;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class BPMService implements IBPMService, Serializable {
	private static final long serialVersionUID = -4997043941891603319L;

	private final static Logger log = Logger.getLogger(BPMService.class);

	@Autowired
	private RuntimeService runtimeService;

	@Autowired
	private TaskService taskService;

	@Autowired
	IdentityService identityService;

	@Override
	public void firstTest() {
		runtimeService.startProcessInstanceByKey("activitiReview");
	}

	@Override
	public void startProductionProcess(Long pedidoVenta, Long prodId, String itemCode, String author, Integer itemState) {
		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put("pedido_venta_id", pedidoVenta);
		variables.put("orden_prod_id", prodId);
		variables.put("item_code", itemCode);
		variables.put("item_state", itemState);
		variables.put("author", author);
		runtimeService.startProcessInstanceByKey("proceso-produccion", variables);
	}

	@Override
	public List<Task> getTasksByGroup(List<String> userGroups) {
		TaskQuery taskQuery = taskService.createTaskQuery();
		taskQuery.taskCandidateGroupIn(userGroups);
		taskQuery.includeProcessVariables();
		taskQuery.includeTaskLocalVariables();
		List<Task> tasks = taskQuery.list();
		for (Task task : tasks) {
			log.info("Task available: " + task.getName());
		}
		return tasks;
	}

	public void updateUsers() {

	}

	public RuntimeService getRuntimeService() {
		return runtimeService;
	}

	public void setRuntimeService(RuntimeService runtimeService) {
		this.runtimeService = runtimeService;
	}

	@Override
	public Task getTaskById(String executionId) {
		log.debug("Getting task: " + executionId);
		TaskQuery taskQuery = taskService.createTaskQuery();
		taskQuery.executionId(executionId);
		taskQuery.includeProcessVariables();
		List<Task> tasks = taskQuery.list();
		if (tasks != null && !tasks.isEmpty() && tasks.size() == 1) {
			log.debug("Task efinition key: " + tasks.get(0).getTaskDefinitionKey());
			return tasks.get(0);
		} else {
			log.info("Task is not unique");
			return null;
		}
	}

	@Override
	public void completeTask(String taskId, Map<String, Object> variables) {
		taskService.complete(taskId, variables);
	}

	@Override
	public void completeTask(String executionId) {
		taskService.complete(executionId);
	}

	@Override
	public void claimTask(String taskId, String userId) throws ActivitiObjectNotFoundException, ActivitiTaskAlreadyClaimedException {
		taskService.claim(taskId, userId);
	}

	@Override
	public Collection<? extends Task> getTasksByUser(String userEmail) {
		TaskQuery taskQuery = taskService.createTaskQuery();
		taskQuery.taskAssignee(userEmail);
		taskQuery.includeProcessVariables();
		taskQuery.includeTaskLocalVariables();
		List<Task> tasks = taskQuery.list();
		for (Task task : tasks) {
			log.info("Task available: " + task.getName());
		}
		return tasks;
	}
}
